package com.htt.bms.utils;

import com.htt.bms.domain.sys.SysUser;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;

import java.util.*;

/**
 * @author 侯婷婷
 * @version 1.0
 * @description
 */
@Slf4j
public class JwtTokenUtils {

    //请求/响应头中token对应的key
    public static final String TOKEN_HEADER = "Authorization";

    //在某些系统中，前端提交token时会在前面加个固定的前缀，例如："satoken": "Bearer xxxx-xxxx-xxxx-xxxx"
    //此时后端如果不做任何特殊处理，框架将会把Bearer视为token的一部分，无法正常读取token信息，导致鉴权失败。
    public static final String TOKEN_PREFIX = "Bearer";

    //发行者信息
    public static final String ISS = "htt";

    //秘钥
    private static final String SECRET = "jwtsecretdemo";

    //角色key
    private static final String ROLE_CHAIMS = "rol";

    //用户key
    private static final String USER_CHAIMS = "user";

    //过期时间3600*4，即4小时
    private static final long EXPIRATION = 14400000l;

    //选择记住我之后的过期时间为7天
    private static final long EXPIRATION_REMEMBER = 604800l;


    /**
     * 创建token
     * @param user
     * @param isRememberMe
     * @return
     */
    public static String createToken(SysUser user, boolean isRememberMe){
        long expiration = isRememberMe ? EXPIRATION_REMEMBER : EXPIRATION;
        Map<String, Object> map = new HashMap<>();
        map.put(ROLE_CHAIMS, user.getRole());
        map.put(USER_CHAIMS, user);
        return Jwts.builder()
                .signWith(SignatureAlgorithm.HS256, SECRET)
                .setClaims(map)
                .setIssuer(ISS)
                .setSubject(user.getUsername())//jwt所面向的用户
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + expiration))
                .compact();
    }

    /**
     * 从token中获取用户名
     * @param token
     * @return
     */
    public static String getUsername(String token){
        return getTokenBody(token).getSubject();
    }

    /**
     * 获取用户角色
     * @param token
     * @return
     */
    public static String getUserRole(String token){
        return getTokenBody(token).get(ROLE_CHAIMS,String.class);
    }

    /**
     * 获取用户信息
     * @param token
     * @return
     */
    public static SysUser getUser(String token){
        //由于解析出来的token中user的类型是LinkedHashMap，需要将其转换为SysUser类型
        LinkedHashMap<String,Object> map = getTokenBody(token).get(USER_CHAIMS, LinkedHashMap.class);
        return SysUser.builder()
                .id((String) map.get("id"))
                .username((String) map.get("username"))
                .password(String.valueOf(map.get("password")))
                .nickname((String) map.get("nickname"))
                .type((Integer) map.get("type"))
                .role((String) map.get("role"))
                .orgId((Integer) map.get("orgId"))
                .orgIds((List<Integer>) map.get("orgIds"))
                .build();
    }

    /**
     * 判断是否过期
     * @param token
     * @return
     */
    public static boolean isExpiration(String token) {
        try {
            log.info("============过期时间 {}===============",getTokenBody(token).getExpiration());
            return getTokenBody(token).getExpiration().before(new Date());
        } catch (Exception e) {
            return true;
        }
    }

    private static Claims getTokenBody(String token){
        return Jwts.parser()
                .setSigningKey(SECRET)
                .parseClaimsJws(token)
                .getBody();
    }
}
